﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Collections;
using System.Data;
using System.Reflection;
using System.Web;
using System.Web.SessionState;

using WAF.DAO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;

using server.Remote;

namespace server
{
    /// <summary>
    /// Http请求处理入口
    /// </summary>
    /// <remarks>
    /// 被调用的方法的参数必须为HttpContext（由方法自己解析参数）
    /// 被调用的方法的返回类型必须为string（由方法自己格式化输出）
    /// </remarks>
    public class AppEntry : IHttpHandler, IRequiresSessionState
    {
        public void ProcessRequest(HttpContext context)
        {
            string returnJson = string.Empty;

            //try
            {
                //检查参数个数
                if (context.Request.QueryString.Count < 2)
                    throw new Exception("未指定类名或方法名");

                //远程调用的类
                string className = context.Request.QueryString["class"];
                Type classType = Type.GetType("server.Remote." + className);
                object classInstance = Activator.CreateInstance(classType);

                //远程调用的方法
                string methodName = context.Request.QueryString["method"];
                MethodInfo method = classType.GetMethod(methodName);

                //远程调用方法的参数
                object[] parameters = new object[] { context };

                //调用远程方法
                returnJson = method.Invoke(classInstance, parameters).ToString();
            }
            //catch (Exception ex)
            {
                //返回错误提示
                //returnJson = MyHandler.WriteSuccessResult(false, ex.Message);
            }

            //输出应答
            context.Response.ContentType = "text/plain";
            context.Response.Write(returnJson);
        }

        /// <summary>
        /// 对每一个请求都使用新的实例来处理
        /// </summary>
        public bool IsReusable
        {
            get { return false; }
        }

        /// <summary>
        /// 添加调用是否成功标志
        /// </summary>
        /// <param name="isSuccess">调用成功</param>
        /// <param name="result">调用结果</param>
        /// <returns>加成功标志的调用结果</returns>
        public static string WriteSuccessResult(bool isSuccess, string result)
        {
            StringWriter sw = new StringWriter();
            JsonTextWriter jsonWriter = new JsonTextWriter(sw);

            //输出开始
            jsonWriter.WriteStartObject();

            //是否成功
            jsonWriter.WritePropertyName("success");
            jsonWriter.WriteValue(isSuccess);

            //返回数据
            jsonWriter.WritePropertyName("data");
            jsonWriter.WriteRaw(result);

            //输出结束
            jsonWriter.WriteEndObject();
            jsonWriter.Flush();

            return sw.GetStringBuilder().ToString();
        }

        /// <summary>
        /// 获取HttpContext载体中的参数数组
        /// </summary>
        /// <param name="context">HttpContext</param>
        /// <returns>参数数组</returns>
        public static string[] GetPayloadParameter(HttpContext context)
        {
            JArray jArray = JArray.Parse(new StreamReader(context.Request.InputStream).ReadToEnd());

            string[] parameters = new string[jArray.Count];

            for (int i = 0; i < jArray.Count; i++)
                parameters[i] = jArray[i].ToString();

            return parameters;
        }

        /// <summary>
        /// 获取HttpContext载体中的参数
        /// </summary>
        /// <param name="context">HttpContext</param>
        /// <returns>参数</returns>
        public static Dictionary<string, string> GetPayloadObject(HttpContext context)
        {
            string jsonObject = new StreamReader(context.Request.InputStream).ReadToEnd();

            return JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonObject);
        }


        /******************************************* Private *******************************************/


        /// <summary>
        /// 获取指定方法的参数
        /// </summary>
        /// <param name="method">指定的方法</param>
        /// <param name="jsonObject">调用的参数的json对象</param>
        /// <returns>调用所需的参数</returns>
        private object[] GetParams(MethodInfo method, HttpContext context)
        {
            //远程调用的方法参数信息
            ParameterInfo[] parmInfos = method.GetParameters();
            object[] parameters = new object[parmInfos.Length];

            //使用URL中的参数
            if (context.Request.QueryString.Count > 2)
            {
                parameters[0] = context.Request.QueryString;
            }
            //使用载体中的参数
            else
            {
                JArray jArray = JArray.Parse(new StreamReader(context.Request.InputStream).ReadToEnd());

                for (int i = 0; i < parameters.Length; i++)
                    parameters[i] = jArray[i].ToString();
            }

            return parameters;
        }


        /// <summary>
        /// 获取返回值的json字符串
        /// </summary>
        /// <param name="isSuccess">方法是否调用成功</param>
        /// <param name="returnValue">方法返回的值</param>
        /// <returns>生成好的json字符串</returns>
        private string GetReturnJson(bool isSuccess, object data)
        {
            Type dataType = data.GetType();
            StringWriter sw = new StringWriter();
            JsonTextWriter jsonWriter = new JsonTextWriter(sw);

            jsonWriter.WriteStartObject();

            //是否成功
            jsonWriter.WritePropertyName("success");
            jsonWriter.WriteValue(isSuccess);

            //返回数据
            jsonWriter.WritePropertyName("data");

            if (dataType.IsValueType || dataType.Name == "String")
                jsonWriter.WriteValue(data);
            else if (dataType.Name == "DataTable")
                jsonWriter.WriteRaw(JsonConvert.SerializeObject(data, new DataTableConverter()));
            else if (dataType.IsClass)
                jsonWriter.WriteRaw(JsonConvert.SerializeObject(data));

            //输出结束
            jsonWriter.WriteEndObject();
            jsonWriter.Flush();

            return sw.GetStringBuilder().ToString();
        }
    }
}